#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "../src/estep.c"

typedef struct _EstepClampTestDatum EstepClampTestDatum ;
struct _EstepClampTestDatum 
{ 
  struct
    {
      float    priorz[5];
      Rating   ratings[8];
      float    alpha[4 * 5 * 5];
      float    logbeta;
      int      clamp;
    }                   inputs;

  float pz[5];
};

static void
test_estep_clamp (void)
{
  EstepClampTestDatum data[] = 
    {{{{0.209022, 0.830187, 0.115055, 0.0412446,  0.113072}, {{0, 2}, {3, 0}, {0, 0}, {2, 4}, {0, 3}, {2, 0}, {2,  1}, {0, 2}}, {-1., 0.0399869, 0.175461, 0.207223, 0.863151,  0.0701737, -1., 0.69092, 0.443449, 0.831988, 0.521848,  0.314891, -1., 0.137769, 0.531127, 0.0373187, 0.617232,  0.0176111, -1., 0.0714401, 0.538349, 0.654999, 0.0970763,  0.862418, -1., -1., 0.708162, 0.539944, 0.0558317, 0.749346,  0.668175, -1., 0.364483, 0.848608, 0.886195, 0.598001,  0.673564, -1., 0.405159, 0.0542076, 0.0761535, 0.358673,  0.267391, -1., 0.523081, 0.0388347, 0.741441, 0.249779,  0.451641, -1., -1., 0.500486, 0.0864427, 0.152703, 0.589223,  0.792324, -1., 0.546499, 0.0968715, 0.839877, 0.124149,  0.182016, -1., 0.248263, 0.953681, 0.526148, 0.508452,  0.843104, -1., 0.899474, 0.449995, 0.149779, 0.575713,  0.376393, -1., -1., 0.41116, 0.408338, 0.325934, 0.924752,  0.910674, -1., 0.321895, 0.173231, 0.335529, 0.11835,  0.775396, -1., 0.0763592, 0.495652, 0.994201, 0.593381,  0.828096, -1., 0.54197, 0.468052, 0.0849284, 0.984992,  0.642497, -1.}, 0.0180578, 3}, {0.0000524016, 7.68973e-7,  0.0000144618, 0.999928,  4.20696e-6}}, {{{0.409279, 0.266104, 0.606898, 0.526811,  0.0833453}, {{2, 1}, {3, 4}, {2, 4}, {1, 0}, {0, 2}, {0, 3}, {3,  3}, {2, 1}}, {-1., 0.341352, 0.696224, 0.204916, 0.910115,  0.00582359, -1., 0.577874, 0.429519, 0.833755, 0.510172,  0.583673, -1., 0.836139, 0.00565913, 0.968202, 0.115621,  0.75121, -1., 0.0206667, 0.325705, 0.0975632, 0.816061,  0.611388, -1., -1., 0.0596012, 0.490665, 0.28925, 0.528042,  0.718249, -1., 0.794442, 0.0843342, 0.617928, 0.712425,  0.216568, -1., 0.654815, 0.784172, 0.202254, 0.632894,  0.818676, -1., 0.778513, 0.234052, 0.517273, 0.0674654,  0.757847, -1., -1., 0.908347, 0.41971, 0.251404, 0.146459,  0.848746, -1., 0.929045, 0.962154, 0.618417, 0.130497,  0.134603, -1., 0.87782, 0.000489001, 0.418071, 0.918035, 0.223005,  -1., 0.216317, 0.215818, 0.285141, 0.404329, 0.437803, -1., -1.,  0.981766, 0.767868, 0.336864, 0.679957, 0.0734188, -1., 0.348158,  0.0854597, 0.533498, 0.224673, 0.419113, -1., 0.123306, 0.915081,  0.0941759, 0.28451, 0.245486, -1., 0.914592, 0.676104, 0.366475,  0.0224806, 0.698276, -1.}, 0.460287, -1}, {0.0346194, 0.538945,  0.162654, 0.154254,  0.109528}}, {{{0.618151, 0.260472, 0.478521, 0.313466,  0.281287}, {{3, 3}, {3, 0}, {3, 4}, {3, 1}, {3, 4}, {1, 3}, {1,  4}, {2, 0}}, {-1., 0.580515, 0.405102, 0.965308, 0.195828,  0.0470173, -1., 0.180429, 0.546195, 0.0725221, 0.131936,  0.0862532, -1., 0.261685, 0.827036, 0.217344, 0.410149,  0.89521, -1., 0.804556, 0.519068, 0.949862, 0.813877,  0.186405, -1., -1., 0.258596, 0.471341, 0.500411, 0.905117,  0.678081, -1., 0.0662395, 0.535103, 0.709289, 0.631063,  0.88581, -1., 0.988909, 0.636767, 0.499127, 0.799557,  0.727224, -1., 0.809731, 0.281784, 0.389408, 0.832014,  0.00517512, -1., -1., 0.762715, 0.439546, 0.0181373, 0.818771,  0.504119, -1., 0.968205, 0.517726, 0.913653, 0.826039,  0.901965, -1., 0.982623, 0.204364, 0.194975, 0.0161548,  0.993714, -1., 0.567597, 0.695848, 0.216598, 0.26649,  0.757866, -1., -1., 0.414064, 0.827189, 0.434476, 0.752691,  0.651349, -1., 0.387643, 0.416339, 0.93392, 0.14723,  0.419438, -1., 0.898613, 0.0202667, 0.321191, 0.517473,  0.91599, -1., 0.815903, 0.126216, 0.501318, 0.922276,  0.248306, -1.}, 0.430368, -1}, {0.0285219, 0.000636847,  0.000516794, 0.0261267,  0.944198}}, {{{0.655785, 0.49044, 0.0163034, 0.457532,  0.221309}, {{3, 4}, {1, 1}, {2, 3}, {2, 1}, {0, 0}, {3, 2}, {0,  4}, {3, 2}}, {-1., 0.737749, 0.364954, 0.0698886, 0.80497,  0.803829, -1., 0.217725, 0.65045, 0.906357, 0.783562,  0.896534, -1., 0.132977, 0.990367, 0.96766, 0.770318,  0.631659, -1., 0.0680914, 0.719354, 0.33995, 0.346938,  0.412306, -1., -1., 0.228914, 0.323647, 0.889407, 0.190997,  0.491165, -1., 0.958692, 0.819518, 0.386028, 0.687336,  0.740968, -1., 0.169068, 0.479671, 0.903774, 0.844434,  0.0360906, -1., 0.489304, 0.936114, 0.0741159, 0.404432,  0.421213, -1., -1., 0.21676, 0.734166, 0.0574932, 0.00890666,  0.987846, -1., 0.410519, 0.168086, 0.817909, 0.496681,  0.451827, -1., 0.348568, 0.431881, 0.809345, 0.710859,  0.1795, -1., 0.95221, 0.905571, 0.866425, 0.14341,  0.462906, -1., -1., 0.969457, 0.792309, 0.738978, 0.0416932,  0.752698, -1., 0.0581435, 0.681485, 0.0327866, 0.764852,  0.647625, -1., 0.513399, 0.214877, 0.268171, 0.195798,  0.16483, -1., 0.782996, 0.458826, 0.484939, 0.98533,  0.830786, -1.}, 0.553255, 1}, {7.16309e-8, 1., 2.18193e-7,  2.30238e-8,  8.78337e-8}}, {{{0.84192, 0.36788, 0.583798, 0.826205,  0.102942}, {{1, 1}, {1, 2}, {3, 3}, {1, 0}, {1, 2}, {3, 4}, {1,  4}, {1, 1}}, {-1., 0.326186, 0.8311, 0.768061, 0.421457,  0.2934, -1., 0.0662485, 0.120437, 0.908059, 0.0785225,  0.798077, -1., 0.924639, 0.743228, 0.295527, 0.339251,  0.4397, -1., 0.757898, 0.464741, 0.785996, 0.821186,  0.915978, -1., -1., 0.0968612, 0.202198, 0.994981, 0.813036,  0.770675, -1., 0.371097, 0.22692, 0.391579, 0.477275,  0.304849, -1., 0.106484, 0.48352, 0.398752, 0.506772,  0.181845, -1., 0.740292, 0.103226, 0.167521, 0.742145,  0.982394, -1., -1., 0.638485, 0.381525, 0.920959, 0.0664158,  0.541624, -1., 0.179327, 0.925978, 0.25338, 0.770949,  0.80823, -1., 0.699058, 0.861801, 0.293674, 0.503381,  0.592574, -1., 0.378281, 0.894922, 0.99661, 0.410729,  0.637989, -1., -1., 0.791696, 0.829089, 0.668584, 0.655595,  0.153211, -1., 0.447564, 0.747624, 0.58918, 0.611587,  0.268236, -1., 0.821646, 0.3358, 0.840638, 0.460006,  0.122589, -1., 0.473998, 0.546964, 0.956625, 0.530015,  0.0957174, -1.}, 0.652042, 2}, {5.21033e-7, 1.14399e-6,  0.999987, 2.75713e-7,  0.0000112312}}, {{{0.119286, 0.457728, 0.860346, 0.130927,  0.450702}, {{2, 4}, {0, 3}, {0, 3}, {3, 1}, {2, 3}, {2, 1}, {3,  4}, {0, 3}}, {-1., 0.802133, 0.707135, 0.683363, 0.703077,  0.212953, -1., 0.0955477, 0.415126, 0.881431, 0.877154,  0.254909, -1., 0.95512, 0.758842, 0.403155, 0.707945,  0.998495, -1., 0.228827, 0.307438, 0.0559028, 0.0384791,  0.109542, -1., -1., 0.84971, 0.195557, 0.907552, 0.65884,  0.0475768, -1., 0.488421, 0.224189, 0.955763, 0.834623,  0.392874, -1., 0.809063, 0.0743319, 0.95747, 0.137964,  0.853943, -1., 0.31549, 0.554314, 0.430019, 0.855448,  0.0866624, -1., -1., 0.246876, 0.374116, 0.816969, 0.977121,  0.397167, -1., 0.17856, 0.909417, 0.318281, 0.34959,  0.690138, -1., 0.685227, 0.362518, 0.514966, 0.297265,  0.876164, -1., 0.288186, 0.557497, 0.1593, 0.0222212,  0.972696, -1., -1., 0.00318251, 0.729281, 0.166773, 0.886034,  0.756306, -1., 0.355165, 0.349804, 0.908913, 0.359139,  0.176605, -1., 0.440387, 0.590633, 0.00954956, 0.486467,  0.75516, -1., 0.228115, 0.494583, 0.189202, 0.878996,  0.939929, -1.}, 0.937086, -1}, {3.27195e-9, 0.0000980644,  8.61584e-9, 0.994054,  0.00584807}}, {{{0.856774, 0.967233, 0.933904, 0.30062,  0.690001}, {{2, 0}, {3, 3}, {3, 4}, {0, 4}, {1, 2}, {2, 0}, {0,  1}, {0, 4}}, {-1., 0.0811988, 0.177598, 0.945456, 0.340197,  0.172286, -1., 0.818458, 0.768851, 0.89981, 0.581653,  0.808909, -1., 0.282384, 0.144651, 0.353538, 0.314325,  0.0931818, -1., 0.265655, 0.41361, 0.377239, 0.0632801,  0.408881, -1., -1., 0.446377, 0.443336, 0.76266, 0.718879,  0.365178, -1., 0.265738, 0.817204, 0.378682, 0.192893,  0.44728, -1., 0.0483535, 0.478871, 0.61124, 0.638371,  0.76597, -1., 0.334221, 0.257701, 0.324046, 0.672788,  0.0685659, -1., -1., 0.844091, 0.946807, 0.609508, 0.659685,  0.397714, -1., 0.503471, 0.846848, 0.940806, 0.0325357,  0.237733, -1., 0.0296443, 0.562124, 0.839643, 0.790453,  0.981291, -1., 0.0832529, 0.228403, 0.152082, 0.215321,  0.749032, -1., -1., 0.970702, 0.828036, 0.542533, 0.680466,  0.12661, -1., 0.88123, 0.933025, 0.0207808, 0.728896,  0.377759, -1., 0.086177, 0.0799747, 0.69636, 0.140026,  0.0565327, -1., 0.51785, 0.856718, 0.349572, 0.075242,  0.434597, -1.}, 0.628314, -1}, {0.12417, 0.00149561, 0.0730587,  0.000297333,  0.800978}}, {{{0.859921, 0.685565, 0.657612, 0.369454,  0.317388}, {{2, 0}, {2, 2}, {3, 1}, {1, 3}, {1, 2}, {1, 3}, {1,  3}, {3, 3}}, {-1., 0.00509921, 0.531002, 0.488224, 0.384363,  0.984318, -1., 0.802106, 0.110466, 0.298186, 0.904344,  0.105745, -1., 0.97044, 0.241653, 0.386493, 0.249028,  0.620868, -1., 0.166411, 0.951896, 0.620713, 0.423378,  0.30649, -1., -1., 0.266331, 0.963101, 0.0539237, 0.989102,  0.261231, -1., 0.432099, 0.565699, 0.60474, 0.276913,  0.629993, -1., 0.455234, 0.306554, 0.372569, 0.524248,  0.484793, -1., 0.0649013, 0.986076, 0.27522, 0.863925,  0.898491, -1., -1., 0.03418, 0.654506, 0.440547, 0.592001,  0.767849, -1., 0.691405, 0.386624, 0.602898, 0.506618,  0.259307, -1., 0.820924, 0.998159, 0.229705, 0.629314,  0.365691, -1., 0.691605, 0.857136, 0.105066, 0.880898,  0.626703, -1., -1., 0.87106, 0.829846, 0.0169724, 0.728213,  0.83688, -1., 0.17534, 0.576425, 0.136212, 0.0690307,  0.483934, -1., 0.189801, 0.533314, 0.562413, 0.224628,  0.368877, -1., 0.535155, 0.332707, 0.595314, 0.00318602,  0.84355, -1.}, 0.475572, -1}, {0.0025423, 0.000200069, 0.010806,  0.986451,  4.0423e-7}}, {{{0.122288, 0.216847, 0.604512, 0.660402,  0.105316}, {{1, 3}, {1, 4}, {1, 2}, {3, 1}, {1, 3}, {3, 4}, {0,  1}, {1, 4}}, {-1., 0.488634, 0.767631, 0.485063, 0.528891,  0.352422, -1., 0.698601, 0.00112818, 0.33909, 0.819108,  0.136188, -1., 0.7765, 0.970213, 0.283953, 0.803481,  0.181186, -1., 0.967027, 0.440403, 0.327909, 0.690937,  0.844738, -1., -1., 0.223556, 0.723398, 0.0305351, 0.739422,  0.734922, -1., 0.955766, 0.545473, 0.210531, 0.3825,  0.257165, -1., 0.544344, 0.871442, 0.563392, 0.120977,  0.767844, -1., 0.901229, 0.279439, 0.317497, 0.586658,  0.934202, -1., -1., 0.839036, 0.989587, 0.895721, 0.0894637,  0.61548, -1., 0.26619, 0.865186, 0.350041, 0.880558,  0.310423, -1., 0.319713, 0.13951, 0.498058, 0.0532578,  0.775369, -1., 0.268068, 0.934666, 0.932281, 0.00752444,  0.366839, -1., -1., 0.655227, 0.614784, 0.420866, 0.432637,  0.816191, -1., 0.625197, 0.525146, 0.343173, 0.200711,  0.359007, -1., 0.65996, 0.993132, 0.320152, 0.0485838,  0.340247, -1., 0.853622, 0.822094, 0.995326, 0.564879,  0.585554, -1.}, 0.887428, -1}, {0.0001776, 0.610174, 0.00368326,  0.0462743,  0.339691}}, {{{0.557354, 0.218715, 0.232201, 0.448261,  0.136488}, {{1, 3}, {0, 3}, {3, 4}, {2, 3}, {0, 0}, {3, 3}, {2,  4}, {1, 1}}, {-1., 0.786078, 0.41601, 0.823065, 0.611342,  0.442905, -1., 0.215299, 0.464058, 0.951382, 0.449773,  0.895147, -1., 0.415474, 0.611135, 0.596151, 0.073053,  0.420148, -1., 0.0462562, 0.0105966, 0.185625, 0.357102,  0.488902, -1., -1., 0.791882, 0.953425, 0.908841, 0.352414,  0.0058039, -1., 0.537415, 0.0857762, 0.741072, 0.562899,  0.322116, -1., 0.621719, 0.78969, 0.113127, 0.426969,  0.206245, -1., 0.178555, 0.516976, 0.353916, 0.786097,  0.132298, -1., -1., 0.506379, 0.168291, 0.428995, 0.643396,  0.714498, -1., 0.214866, 0.520154, 0.290982, 0.708694,  0.677451, -1., 0.434378, 0.549911, 0.145794, 0.355335,  0.812659, -1., 0.760221, 0.0326678, 0.928366, 0.606414,  0.581667, -1., -1., 0.515692, 0.57445, 0.820317, 0.449368,  0.00931247, -1., 0.406159, 0.391323, 0.805972, 0.294815,  0.191293, -1., 0.871169, 0.514989, 0.586121, 0.513842,  0.436791, -1., 0.965079, 0.440327, 0.158506, 0.624132,  0.204857, -1.}, 0.407659, -1}, {0.00113803, 0.00347932,  0.000252011, 0.937582, 0.0575485}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      float pz[5];
      float logpriorz[5];

      for (unsigned int j = 0; j < 5; ++j) { pz[j] = drand48 (); }
      for (unsigned int j = 0; j < 5; ++j) { logpriorz[j] = log (data[i].inputs.priorz[j]); }


      estep (data[i].inputs.alpha,
             5,
             data[i].inputs.logbeta,
             pz,
             logpriorz,
             data[i].inputs.clamp,
             data[i].inputs.ratings,
             8,
             0);

      for (unsigned int j = 0; j < 5; ++j)
        {
          assert (fabs (pz[j] - data[i].pz[j]) <=
                  1e-4 * (1 + fabs (pz[j]) + fabs (data[i].pz[j])) ||
                  (fprintf (stderr, "%u: %g ?= %g\n", j, pz[j], data[i].pz[j]), 0));
        }
    }
}

static void
test_estep_clamp_symmetric (void)
{
  EstepClampTestDatum data[] = 
    {{{{0.0177182, 0.623191, 0.891967, 0.655691,  0.197401}, {{2, 3}, {0, 2}, {0, 2}, {0, 3}, {1, 1}, {1, 2}, {0,  4}, {3, 1}}, {-1., 0.173822, 0.882655, 0.249532, 0.806078,  0.367851, -1., 0.58784, 0.0582388, 0.93491, 0.852861,  0.00171858, -1., 0.544397, 0.498118, 0.887783, 0.561392,  0.385891, -1., 0.873986, 0.682925, 0.153733, 0.15575,  0.856268, -1., -1., 0.0597347, 0.261766, 0.50006, 0.658867,  0.885912, -1., 0.379111, 0.250528, 0.852788, 0.518062,  0.791272, -1., 0.19229, 0.917879, 0.665201, 0.789553,  0.647892, -1., 0.41976, 0.777418, 0.228161, 0.262002,  0.545775, -1., -1., 0.0944926, 0.0744282, 0.106251, 0.689507,  0.0347579, -1., 0.812662, 0.606191, 0.0306402, 0.148846,  0.433551, -1., 0.355663, 0.177852, 0.630784, 0.642279,  0.163374, -1., 0.259973, 0.965583, 0.852726, 0.515481,  0.840213, -1., -1., 0.188165, 0.624565, 0.25348, 0.294438,  0.0936727, -1., 0.550137, 0.147228, 0.604931, 0.0589148,  0.737475, -1., 0.541037, 0.574291, 0.910069, 0.303924,  0.185374, -1., 0.396439, 0.279285, 0.661644, 0.0220003,  0.136466, -1.}, 0.313702, 4}, {1.09241e-6, 0.0000219291,  0.000505946, 0.0000498745,  0.999421}}, {{{0.506519, 0.296253, 0.125537, 0.184353,  0.253039}, {{2, 1}, {2, 2}, {3, 4}, {2, 1}, {3, 4}, {0, 2}, {2,  4}, {2, 2}}, {-1., 0.00181513, 0.0318642, 0.634216, 0.105811,  0.396884, -1., 0.972949, 0.896741, 0.564774, 0.822593,  0.0628801, -1., 0.592818, 0.3794, 0.426154, 0.783595,  0.931173, -1., 0.3574, 0.289688, 0.469893, 0.122255,  0.850881, -1., -1., 0.993435, 0.344356, 0.937902, 0.597841,  0.99162, -1., 0.312492, 0.303686, 0.49203, 0.594736,  0.339542, -1., 0.406945, 0.927257, 0.772143, 0.276662,  0.814127, -1., 0.547857, 0.345989, 0.493067, 0.882954,  0.190457, -1., -1., 0.0563009, 0.0231748, 0.760698, 0.339576,  0.0628661, -1., 0.678819, 0.822796, 0.741735, 0.0712464,  0.366328, -1., 0.51911, 0.249705, 0.476511, 0.0267854,  0.112165, -1., 0.322448, 0.704368, 0.750123, 0.298038,  0.774591, -1., -1., 0.358379, 0.257056, 0.415085, 0.584134,  0.302078, -1., 0.233881, 0.654386, 0.244558, 0.239212,  0.555062, -1., 0.83159, 0.502823, 0.167966, 0.188735,  0.31248, -1., 0.253119, 0.691455, 0.161949, 0.200315,  0.930671, -1.}, 0.987087, -1}, {0.00223176, 0.00278135, 0.185679,  2.31347e-6,  0.809305}}, {{{0.902277, 0.156079, 0.628708, 0.15477,  0.487192}, {{0, 1}, {1, 4}, {2, 1}, {2, 3}, {2, 4}, {2, 3}, {0,  3}, {1, 2}}, {-1., 0.571945, 0.32663, 0.920888, 0.832806,  0.327387, -1., 0.0874176, 0.365826, 0.00121588, 0.824564,  0.919452, -1., 0.177091, 0.688736, 0.571445, 0.227997,  0.0151422, -1., 0.48842, 0.640775, 0.24091, 0.603316,  0.586143, -1., -1., 0.484695, 0.612202, 0.448547, 0.0989509,  0.91275, -1., 0.285572, 0.527658, 0.266145, 0.585363,  0.198154, -1., 0.161832, 0.264929, 0.760799, 0.278702,  0.984741, -1., 0.576193, 0.189354, 0.0507057, 0.969598,  0.0877731, -1., -1., 0.548579, 0.809796, 0.366282, 0.50163,  0.0638841, -1., 0.197595, 0.917735, 0.402679, 0.151134,  0.912023, -1., 0.390077, 0.136534, 0.565771, 0.713868,  0.228245, -1., 0.871605, 0.804971, 0.435166, 0.243505,  0.295412, -1., -1., 0.615617, 0.38446, 0.273906, 0.207639,  0.067038, -1., 0.574664, 0.907624, 0.706009, 0.00315399,  0.377069, -1., 0.989889, 0.30333, 0.85202, 0.465047,  0.599812, -1., 0.166796, 0.28625, 0.751179, 0.371567,  0.295191, -1.}, 0.481278, -1}, {0.00387609, 0.0398413, 0.287036,  0.475163,  0.194084}}, {{{0.128062, 0.999779, 0.865661, 0.931553,  0.854156}, {{1, 1}, {3, 3}, {3, 3}, {3, 1}, {2, 2}, {1, 3}, {0,  3}, {0, 0}}, {-1., 0.792141, 0.798623, 0.356889, 0.946532,  0.0861321, -1., 0.795469, 0.979819, 0.956642, 0.782802,  0.943449, -1., 0.514772, 0.356831, 0.616006, 0.657199,  0.763594, -1., 0.985264, 0.320815, 0.175921, 0.447581,  0.857201, -1., -1., 0.321036, 0.31026, 0.516028, 0.00304539,  0.528895, -1., 0.511637, 0.15914, 0.0565138, 0.442763,  0.716169, -1., 0.179321, 0.0998713, 0.659961, 0.77272,  0.664549, -1., 0.743041, 0.0439546, 0.115521, 0.900955,  0.757777, -1., -1., 0.72314, 0.9396, 0.453374, 0.900576,  0.402104, -1., 0.62934, 0.937346, 0.89753, 0.873209,  0.117702, -1., 0.778206, 0.841017, 0.430447, 0.401534,  0.598885, -1., 0.741145, 0.770486, 0.628814, 0.934336,  0.998104, -1., -1., 0.726531, 0.513293, 0.0333809, 0.240327,  0.00339183, -1., 0.573694, 0.580007, 0.339752, 0.601288,  0.944354, -1., 0.642661, 0.442221, 0.728079, 0.826651,  0.864456, -1., 0.601204, 0.297632, 0.425117, 0.265571,  0.860059, -1.}, 0.527146, 3}, {2.1598e-9, 4.54873e-9,  5.63385e-10, 1.,  1.04291e-11}}, {{{0.331235, 0.861955, 0.800615, 0.28301,  0.297854}, {{0, 3}, {3, 1}, {1, 1}, {2, 3}, {0, 0}, {2, 4}, {0,  3}, {2, 3}}, {-1., 0.621627, 0.797223, 0.709316, 0.717847,  0.281876, -1., 0.195935, 0.764963, 0.0751858, 0.839655,  0.467856, -1., 0.938311, 0.21073, 0.23845, 0.170224,  0.513194, -1., 0.945159, 0.378391, 0.643078, 0.716891,  0.613925, -1., -1., 0.516436, 0.842463, 0.433881, 0.316071,  0.894809, -1., 0.0452404, 0.724565, 0.598224, 0.612933,  0.849305, -1., 0.959602, 0.523038, 0.773278, 0.381449,  0.0212906, -1., 0.312308, 0.534828, 0.211225, 0.508097,  0.367148, -1., -1., 0.156437, 0.568146, 0.791206, 0.753223,  0.64, -1., 0.725683, 0.357325, 0.437153, 0.745191, 0.680443, -1.,  0.63276, 0.838929, 0.132258, 0.831137, 0.673158, -1., 0.315891,  0.35898, 0.449688, 0.651868, 0.00358367, -1., -1., 0.824152,  0.238464, 0.143771, 0.636436, 0.667715, -1., 0.670317, 0.352565,  0.883212, 0.0277145, 0.944634, -1., 0.995241, 0.446059, 0.282523,  0.264191, 0.36248, -1., 0.60713, 0.150265, 0.433054, 0.689322,  0.291239, -1.}, 0.791285, 3}, {4.16245e-12, 1.33963e-9,  1.80658e-13, 1.,  7.81326e-12}}, {{{0.0374538, 0.287655, 0.967133, 0.744902,  0.893683}, {{3, 0}, {1, 1}, {2, 4}, {3, 4}, {0, 0}, {0, 0}, {1,  3}, {3, 0}}, {-1., 0.65122, 0.299418, 0.0745845, 0.541117,  0.768008, -1., 0.271704, 0.12995, 0.545876, 0.321948,  0.989181, -1., 0.865759, 0.183396, 0.714818, 0.838916,  0.432705, -1., 0.494075, 0.423579, 0.0476309, 0.449339,  0.456621, -1., -1., 0.135924, 0.0804979, 0.704437, 0.562938,  0.484704, -1., 0.78108, 0.629853, 0.0218212, 0.716696,  0.509376, -1., 0.499903, 0.475945, 0.394748, 0.520196,  0.634144, -1., 0.292548, 0.67993, 0.68128, 0.201439,  0.798474, -1., -1., 0.256351, 0.633649, 0.7521, 0.341853,  0.120427, -1., 0.553151, 0.0476627, 0.778915, 0.635723,  0.772071, -1., 0.41781, 0.757094, 0.919027, 0.262695,  0.917907, -1., 0.281149, 0.52428, 0.742499, 0.283763,  0.988601, -1., -1., 0.84435, 0.0612198, 0.0823243, 0.190127,  0.587999, -1., 0.427571, 0.330224, 0.848273, 0.467572,  0.87442, -1., 0.282562, 0.0693585, 0.831849, 0.102349,  0.864752, -1., 0.312265, 0.912822, 0.839654, 0.946845,  0.0311158, -1.}, 0.388543, -1}, {0.489163, 0.000235901,  0.00438569, 0.102043,  0.404172}}, {{{0.663081, 0.0425152, 0.544193, 0.0359348,  0.580757}, {{3, 0}, {0, 3}, {3, 4}, {0, 3}, {0, 2}, {3, 0}, {1,  3}, {1, 3}}, {-1., 0.852389, 0.956193, 0.608364, 0.250533,  0.00411518, -1., 0.488621, 0.733944, 0.967971, 0.934757,  0.656771, -1., 0.631595, 0.103219, 0.622492, 0.743949,  0.79194, -1., 0.156374, 0.591376, 0.355407, 0.694786,  0.493293, -1., -1., 0.548861, 0.811214, 0.658851, 0.912536,  0.696472, -1., 0.855021, 0.0504874, 0.662003, 0.692357,  0.3664, -1., 0.316544, 0.694033, 0.7576, 0.709629, 0.684949, -1.,  0.590814, 0.135109, 0.965679, 0.893009, 0.434439, -1., -1.,  0.543732, 0.610273, 0.198223, 0.941146, 0.994871, -1., 0.799058,  0.539372, 0.0286105, 0.298399, 0.944037, -1., 0.488884, 0.366607,  0.606042, 0.577637, 0.172341, -1., 0.672574, 0.848441, 0.868008,  0.487391, 0.0817607, -1., -1., 0.713333, 0.902329, 0.594382,  0.647321, 0.169601, -1., 0.292056, 0.39616, 0.706175, 0.174729,  0.492998, -1., 0.856788, 0.677564, 0.87633, 0.54896,  0.367903, -1., 0.310957, 0.270288, 0.971323, 0.195563,  0.638383, -1.}, 0.421847, -1}, {0.0708531, 0.000145551,  0.00644158, 0.873344,  0.0492157}}, {{{0.708172, 0.556622, 0.708514, 0.200987,  0.113789}, {{1, 4}, {3, 4}, {3, 0}, {2, 2}, {2, 0}, {0, 1}, {0,  4}, {3, 1}}, {-1., 0.909301, 0.538913, 0.908931, 0.71763,  0.203126, -1., 0.364184, 0.415933, 0.860842, 0.525562,  0.487854, -1., 0.866973, 0.492939, 0.214604, 0.217566,  0.895649, -1., 0.297376, 0.576221, 0.795719, 0.792334,  0.589204, -1., -1., 0.0195992, 0.0872056, 0.591347, 0.475415,  0.110298, -1., 0.548292, 0.682416, 0.757785, 0.907172,  0.184108, -1., 0.266483, 0.896943, 0.38161, 0.696254,  0.39951, -1., 0.404004, 0.167006, 0.478688, 0.503861,  0.106629, -1., -1., 0.590785, 0.682969, 0.711527, 0.517425,  0.571185, -1., 0.595763, 0.12018, 0.0420099, 0.460887,  0.0474708, -1., 0.437763, 0.284225, 0.553715, 0.863363,  0.17128, -1., 0.387282, 0.172105, 0.167108, 0.77177,  0.983277, -1., -1., 0.00509885, 0.68842, 0.267909, 0.876649,  0.414314, -1., 0.00545152, 0.556382, 0.359224, 0.843129,  0.409688, -1., 0.436202, 0.317214, 0.382242, 0.362218,  0.998439, -1., 0.032989, 0.828527, 0.498855, 0.827159,  0.645707, -1.}, 0.656422, -1}, {0.163629, 0.198073, 0.0293674,  0.00213332,  0.606798}}, {{{0.0553891, 0.66243, 0.651323, 0.643326,  0.78748}, {{3, 3}, {3, 0}, {3, 1}, {1, 2}, {2, 1}, {3, 0}, {2,  3}, {3, 1}}, {-1., 0.785781, 0.237009, 0.637875, 0.231098,  0.426558, -1., 0.39388, 0.228186, 0.794896, 0.109344,  0.011638, -1., 0.865969, 0.796457, 0.0763548, 0.183111,  0.367114, -1., 0.969298, 0.430647, 0.526689, 0.0353673,  0.913909, -1., -1., 0.768218, 0.875366, 0.392041, 0.126429,  0.982436, -1., 0.638357, 0.754166, 0.895331, 0.555878,  0.244477, -1., 0.52598, 0.100435, 0.446535, 0.232839,  0.660011, -1., 0.303978, 0.37018, 0.0497282, 0.292897,  0.33468, -1., -1., 0.939532, 0.523039, 0.25753, 0.420771,  0.171315, -1., 0.647673, 0.865489, 0.294342, 0.188879,  0.00931595, -1., 0.111322, 0.399011, 0.633, 0.764839,  0.585343, -1., 0.298577, 0.186466, 0.531999, 0.925331,  0.994599, -1., -1., 0.816286, 0.482271, 0.632434, 0.65992,  0.876754, -1., 0.959232, 0.374904, 0.239149, 0.705439,  0.311559, -1., 0.509416, 0.944807, 0.51656, 0.302243,  0.398093, -1., 0.545796, 0.88356, 0.537404, 0.812751,  0.247219, -1.}, 0.697094, -1}, {0.00190202, 0.883735, 0.0042564,  0.105262,  0.00484465}}, {{{0.887419, 0.25262, 0.880808, 0.523134,  0.254985}, {{0, 1}, {0, 0}, {0, 2}, {1, 2}, {3, 4}, {1, 1}, {3,  1}, {0, 2}}, {-1., 0.5927, 0.00405415, 0.563902, 0.88008,  0.353551, -1., 0.298615, 0.252343, 0.370665, 0.408744,  0.782055, -1., 0.9501, 0.972572, 0.862949, 0.898495,  0.412695, -1., 0.159821, 0.61573, 0.201401, 0.40729,  0.272402, -1., -1., 0.363111, 0.320593, 0.884156, 0.0174172,  0.770411, -1., 0.316539, 0.320254, 0.137337, 0.416859,  0.0179236, -1., 0.0679114, 0.766672, 0.00811516, 0.235869,  0.117812, -1., 0.7941, 0.145166, 0.337374, 0.705116,  0.634279, -1., -1., 0.529436, 0.135973, 0.297826, 0.361877,  0.166326, -1., 0.81538, 0.41367, 0.34446, 0.395915, 0.498841, -1.,  0.0934159, 0.207123, 0.979056, 0.480918, 0.0255045, -1.,  0.440451, 0.970941, 0.245049, 0.907693, 0.646351, -1., -1.,  0.825774, 0.907675, 0.202576, 0.0120718, 0.296338, -1., 0.771702,  0.90475, 0.650195, 0.130012, 0.956322, -1., 0.49108, 0.305735,  0.734097, 0.45748, 0.397664, -1., 0.0986119, 0.755041, 0.976563,  0.372159, 0.658161, -1.}, 0.7841, 2}, {1.08874e-8,  9.5282e-7, 0.999999, 1.68645e-11, 3.43515e-11}}}; 

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      float pz[5];
      float logpriorz[5];

      for (unsigned int j = 0; j < 5; ++j) { pz[j] = drand48 (); }
      for (unsigned int j = 0; j < 5; ++j) { logpriorz[j] = log (data[i].inputs.priorz[j]); }

      estep (data[i].inputs.alpha,
             5,
             data[i].inputs.logbeta,
             pz,
             logpriorz,
             data[i].inputs.clamp,
             data[i].inputs.ratings,
             8,
             1);

      for (unsigned int j = 0; j < 5; ++j)
        {
          assert (fabs (pz[j] - data[i].pz[j]) <=
                  1e-4 * (1 + fabs (pz[j]) + fabs (data[i].pz[j])) ||
                  (fprintf (stderr, "%u: %g ?= %g\n", j, pz[j], data[i].pz[j]), 0));
        }
    }
}

int 
main (void)
{
  srand48 (69);

  test_estep_clamp ();
  test_estep_clamp_symmetric ();

  return 0;
}
